/**
 * 原型链
 */

let ck = {}
console.dir(ck)

let hd = {}
console.dir(hd)

// 获取到父级的方法
console.log(Object.getPrototypeOf(ck));
console.log(Object.getPrototypeOf(ck) === Object.getPrototypeOf(hd));

/**
 * 可以通过Object.create()来定义一个没有父亲的object, 他就没有父亲了， 就是自己
 *
 * */

const noPObj = Object.create(null,
    {
        name: {
            value: "bob"
        }
    }
)
console.log(noPObj)

const newObj = {name: 'bob'}
console.log(newObj.hasOwnProperty('name'))
// 因为这个没有父亲， 就没办法继承父亲的hasOwnProperty()方法， 就会报错。
// console.log(noPObj.hasOwnProperty('name')) // 这里会报错


/**
 * 方法的使用上： 如果自己有调用的方法， 那么就使用自己的，否则，就向上找父级的， 如果有就继承， 否则报错
 */

let ckV1 = {
    name: 'ckv1',
    show() {
        console.log('ckv1 show')
    },
    render() {
        console.log('ckv1 render')
    }
}
ckV1.hasOwnProperty('name')
ckV1.show()
ckV1.render()
// 该方法没有， 进行报错
// ckV1.get()

// 在ckV1的父亲上写一个get方法。
ckV1.__proto__.get= () =>{
    console.log('father get')
}

// 这里调用， 就会成功返回 'father get'
ckV1.get()


/**
 * 方法的原型链 function
 */

let ckVF = function (){}
console.dir(ckVF)
// ckVF中有了__proto__ 和 prototype

/**
 * function中 __Proto__ 和 prototype的区别
 * 函数中的__proto__ 是服务器函数本身的， 因为基本上any都有__proto__父亲
 * 函数中的prototype是服务于构造器new 出来的对象， 这个是函数特有的。
 */

const ckVF1 = new ckVF()
console.log(ckVF1) // 这里是一个对象格式， 不是方法类型了
console.log(typeof ckVF1); // 判断ckVF1的类型， 看看是啥样的 ， 输出为 object

console.dir(ckVF); // 既有prototyped 又有 __proto__。

// 在方法上面， 如果给方法的prototype加上了方法， 那么通过构造方法new 出来的对象是可以继承到这个方法的。
ckVF.prototype.show = () => {
    console.log('ckvf show method')
}

ckVF1.show()

// 只有方法有prototype， 所以，通过new构造的对象， 它有__proto__ , 并且这个玩意就是对象的爸爸， 这个爸爸指向方法的prototype.
console.log(ckVF1.__proto__ === ckVF.prototype)
// prototype是原型， __proto__是爸爸， 只有方法有prototype原型， 其他的都是只有爸爸。
// 也就是说， 通过构造方法new 出来的方法的对象，它的父亲是 方法的原型。
console.log(ckVF.__proto__ === ckVF1.__proto__.prototype)


// 给函数上面挂对象
ckVF.__proto__.view = function () {
    console.log('ckVF method view')
}
// 通过方法名， 直接调用， 就是使用的父亲的方法， 继承过来的
ckVF.view()
